#!/bin/sh

# -----------------------------------------------------------------------
#  Copyright (c) 2010-2011, Plausible Labs Cooperative, Inc.
#  All Rights Reserved.
# 
#  Permission is hereby granted, free of charge, to any person obtaining
#  a copy of this software and associated documentation files (the
#  ``Software''), to deal in the Software without restriction, including
#  without limitation the rights to use, copy, modify, merge, publish,
#  distribute, sublicense, and/or sell copies of the Software, and to
#  permit persons to whom the Software is furnished to do so, subject to
#  the following conditions:
#
#  The above copyright notice and this permission notice shall be included
#  in all copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#  NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
#  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#  DEALINGS IN THE SOFTWARE.
#  -----------------------------------------------------------------------

# Architecture definitions
ARCH="x86_64"
PAGE_SIZE="4096"

# The name of this page
PAGE_NAME=pl_blockimp_table_page

# Prefix to be placed at the start of the trampoline page
trampoline_prefix () {
asm << 'EOF'
    _block_tramp_dispatch:
        pop    %r11
        and    $0xfffffffffffffff8, %r11 // truncate to the trampoline start (each is 8 bytes)
        sub    $0x1000, %r11 // load the config location

        // Move 'self' to the second parameter, overwriting IMP
        movq   %rdi, %rsi
        
        // Load the block reference from the config page, and move to the first parameter
        movq   (%r11), %rdi

        // Jump to the block fptr
        jmp *0x10(%rdi)
        .align 4 // align the trampolines at 16 bytes (required for config page lookup and sizing)
EOF
}

# Generate a single trampoline
trampoline () {
asm << 'EOF'
    // Call into the dispatcher, placing our return address on the stack. 
    call _block_tramp_dispatch # 5 bytes
        .align 4 // align the trampolines at 16 bytes (required for config page lookup and sizing)
EOF
}